#ifndef PILE_H
#define PILE_H

// A NON-EMPTY bunch of labeled metric objects (i.e., Items),
// plus several operations on the bunch.
// This class can't be instantiated, because these methods are pure virtual:
//  - add
//  - get_iterator
//  - size
// Known subclasses:
// Pile_List, Pile_Vector, Pile_Set, Pile_Hash

#include "My_Set.h"
#include "Item.h"
#include "Categorizer.h"

class Pile : public My_Set<Item*> {
public:
    virtual ~Pile();

    // Modifiers (all are pure virtual)

    // Add one item to this pile
    virtual void add(Item *item) = 0;

    // Add a whole pile of items
    virtual void add(Pile *other) = 0;

    // Remove all items
    virtual void clear() = 0;

    // Pick out items from this pile according to categories,
    // group them into new piles.
    virtual void partition(Categorizer& cat,
                           std::vector<Pile*>& parts) = 0;

    // Access
    // also pure virtual
    // Number of items.
    virtual int size() = 0;

    // this one was pure virtual in parent class, will remain so.
    // Iterator<Item*> *get_iterator();

    // Input and Output:
    // All of these are ordinary non-virtual methods.

    // Ingest items from data file.
    void read(const std::string& filename);

    // Save all-to-all distances in this pile
    void save_distances(std::string& file_name);

    // Save all the items
    void write(std::string& file_name);
    void write(std::ostream& os);

    // Save just the items' IDs
    void write_IDs(std::ostream& os);

};

#endif
